package turtle.system.doug.turtleaction;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TreeMap;

import turtle.system.pt.BarSet;
import turtle.system.pt.DailyExec;
import arbor.mining.util.stock.OHLC;
import arbor.mining.util.stock.StockEntity;

public class TurtleActReverseEvaluator {
  public static final String START_TIME = "1999/01/05";
  //public static final String START_TIME = "2008/01/02";
  public static final String END_TIME = "2009/05/19";

  public boolean isRevertAction = false;
  
  public static final String historyFN = "tmp/history_profit.csv";
  TreeMap<Calendar, ArrayList<TurtleAction>> actMap = new TreeMap<Calendar, ArrayList<TurtleAction>>();
  TreeMap<Calendar, ArrayList<TurtleAddAction>> addMap = new TreeMap<Calendar, ArrayList<TurtleAddAction>>();
  TreeMap<String, Double> dayProfitMap = new TreeMap<String, Double>();
  TreeMap<String, StockEntity> allStockPrices = DailyExec
			.getAllStockData(DailyExec.WTX1_PREFIX_FN + DailyExec.FN_SUFFIX);
  ArrayList<Double> histProfit = new ArrayList<Double>();
  private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
  public TurtleActReverseEvaluator(ArrayList<TurtleAction> actList) {
	  for (int i=0;i<actList.size();i++) {
		  if (!actMap.containsKey(actList.get(i).tomorrowBar2.today)) {
			  ArrayList<TurtleAction> r = new ArrayList<TurtleAction>();
			  r.add(actList.get(i));            
			  actMap.put(actList.get(i).tomorrowBar2.today,  r);
		  }
		  else {
			  actMap.get(actList.get(i).tomorrowBar2.today).add(actList.get(i));
		  }
	  }
  }

	

    public int getLotByProfit(double curProfit) {
    	int lot = ((int)curProfit/3000);
    	if (lot<1)
    		lot = 1;
    	if (lot > 30)
    		lot = 30;
    	return lot;
    }
	public int getLot(GregorianCalendar start, String date) {
		GregorianCalendar cur = new GregorianCalendar();
		GregorianCalendar comp = (GregorianCalendar) start.clone();
		int lot = 1;
		try {
			cur.setTime(df.parse(date));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		comp.add(Calendar.YEAR, 1);
		while (cur.after(comp)) {
			comp.add(Calendar.YEAR, 1);
			lot = lot * 2;
		}
		if (lot > 32)
			lot = 32;
		lot = 1;
		return lot;
	}
	public void exec() {
		boolean isNowRevert = false;
		GregorianCalendar start = new GregorianCalendar();
		GregorianCalendar end = new GregorianCalendar();
		GregorianCalendar iterTime = new GregorianCalendar();
		BufferedWriter writer =null;
		try {
		    writer = new BufferedWriter(new FileWriter(historyFN));
		}catch (IOException e) {
			System.out.println(e);
		}
		
		int numRevertInHand = 0; /* 正代表多單數，負代表空單數，0為沒單 */
		int countRevert = 0;
		int numInHand = 0;
		double currentProfit = 0;
		double revertProfit = 0;
		int currentLot = 1;
		
		try {
			start.setTime(df.parse(START_TIME));
			end.setTime(df.parse(END_TIME));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		iterTime.setTime(start.getTime());
		String iterString = df.format(iterTime.getTime());
		double prevClosePrice = allStockPrices.get(iterString).ohlc.close;
		double prevADX = allStockPrices.get(iterString).adx;
		
		while (!iterTime.after(end)) {
			iterString = df.format(iterTime.getTime());
			currentLot = getLot(start, iterString);
			//currentLot = getLotByProfit(currentProfit);
			if (!allStockPrices.containsKey(iterString)) {
				iterTime.add(Calendar.DATE, 1);
				continue; /* 沒開市 */
			}
			else {
				OHLC today = allStockPrices.get(iterString).ohlc;				
								
				if (!actMap.containsKey(iterTime)) {
					/*今天沒動作*/
					currentProfit += (numInHand)* (today.close - prevClosePrice);
					revertProfit += (numRevertInHand)* (today.close - prevClosePrice);
				}
				else {
					/*開盤結算一下*/
					currentProfit += (numInHand)* (today.open - prevClosePrice);
					revertProfit += (numRevertInHand)* (today.open - prevClosePrice);

					ArrayList<TurtleAction> actList = actMap.get(iterTime);					
					int handleTrade = 0;
					/*計算開盤動作*/
					for (int i=0;i<actList.size();i++) {
					  TurtleAction act = actList.get(i);
					  //System.out.println("");
					  //act.getActionMessage();
					  if (act.inOrOut == TurtleAction.IN_ACTION && 
						  act.longOrShort == TurtleAction.LONG_ACTION) {
						  /*一律開盤進場*/		
						  if (countRevert>0) {
						    numRevertInHand-=currentLot;
						    numRevertInHand = 0;
						    isNowRevert = true;
						  }
						  else {
							numRevertInHand+=currentLot;
							isNowRevert = false;
						  }
						  numInHand+=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.OUT_ACTION && 
							  act.longOrShort == TurtleAction.LONG_ACTION &&
							  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_START) {
						  /*開盤出場*/		
						  if (countRevert>0) {
							numRevertInHand+=currentLot;
							numRevertInHand = 0;
							isNowRevert = true;
					      }	
						  else {
						    numRevertInHand-=currentLot;
						    isNowRevert = false;
						  }
						  numInHand-=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.IN_ACTION && 
							  act.longOrShort == TurtleAction.SHORT_ACTION) {
						  /*開盤進場*/
						  if (countRevert>0) {
							numRevertInHand+=currentLot;
							numRevertInHand = 0;
							isNowRevert = true;
					      }				
						  else {
						    numRevertInHand-=currentLot;
						    isNowRevert = false;
						  }
						  numInHand-=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.OUT_ACTION && 
							  act.longOrShort == TurtleAction.SHORT_ACTION &&
							  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_START) {
						  /*開盤出場*/
						  if (countRevert>0) {
							numRevertInHand-=currentLot;
							numRevertInHand = 0;
							isNowRevert = true;
					      }
						  else {
						    numRevertInHand+=currentLot;
						    isNowRevert = false;
						  }
						  numInHand+=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.IN_ACTION && 
					      act.longOrShort == TurtleAction.LONG_ACTION_KEEP_PREV_TRADE_OR_ADVANCED_IN) {
						  	
						  if (countRevert>0) {
							numRevertInHand-=currentLot;
							numRevertInHand = 0;
							//revertProfit -= (currentLot)* (today.open - prevClosePrice);
							isNowRevert = true;
					      }
						  else {
						    numRevertInHand+=currentLot; /*收盤進場*/
						    //revertProfit += (currentLot)* (today.open - prevClosePrice);
						    isNowRevert = false;
						  }
						  currentProfit += (currentLot)* (today.open - prevClosePrice);
						  numInHand+=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.IN_ACTION && 
					      act.longOrShort == TurtleAction.SHORT_ACTION_KEEP_PREV_TRADE_OR_ADVANCED_IN) {
						  
						  if (countRevert>0) {
							numRevertInHand+=currentLot;
							numRevertInHand = 0;
							//revertProfit -= (currentLot)* (prevClosePrice-today.open);
							isNowRevert = true;
					      }
						  else {
						    numRevertInHand-=currentLot; /*收盤進場*/
						    //revertProfit += (currentLot)* (prevClosePrice-today.open);
						    isNowRevert = false;
						  }
						  currentProfit += (currentLot)* (prevClosePrice-today.open);
						  numInHand-=currentLot;
						  handleTrade++;
					  } 			  
					}
					
					/*先假設每一單都撐到最後*/
					revertProfit += (numRevertInHand)* (today.close - today.open);
					currentProfit += (numInHand)* (today.close - today.open);
					
					/*計算盤中動作*/
					for (int i=0;i<actList.size();i++) {
						  TurtleAction act = actList.get(i);
						  if (act.inOrOut == TurtleAction.OUT_ACTION &&
						      act.longOrShort == TurtleAction.LONG_ACTION &&
							  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_INSTANT) {			
							  if (isNowRevert == true) {
								numRevertInHand+=currentLot;
								numRevertInHand = 0;
								//revertProfit += currentLot*(today.close - act.price); /*沒撐到最後*/
							  }
							  else {
							    numRevertInHand-=currentLot;
							    revertProfit -= currentLot*(today.close - act.price); /*沒撐到最後*/
							  }
							  numInHand-=currentLot;
							  currentProfit -= currentLot*(today.close - act.price); /*沒撐到最後*/
							  handleTrade++;
						  }
						  else if (act.inOrOut == TurtleAction.OUT_ACTION &&
							      act.longOrShort == TurtleAction.SHORT_ACTION &&
								  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_INSTANT) {	
							      if (isNowRevert == true) {
								    numRevertInHand-=currentLot;
								    numRevertInHand = 0;
								    //revertProfit += currentLot*(act.price - today.close); /*沒撐到最後*/
								  }
							      else {
								    numRevertInHand+=currentLot;
								    revertProfit -= currentLot*(act.price - today.close); /*沒撐到最後*/
							      }
							      numInHand+=currentLot;
								  currentProfit -= currentLot*(act.price - today.close); /*沒撐到最後*/
								  handleTrade++;
					      } 
					}
							  
					  /*收盤結算一下*/
					for (int i=0;i<actList.size();i++) {
					  TurtleAction act = actList.get(i);
					  if (act.inOrOut == TurtleAction.OUT_ACTION && 
						      act.longOrShort == TurtleAction.LONG_ACTION &&
						      act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_END) {
							  /*收盤出場*/	
						      if (isNowRevert == true) {
							    numRevertInHand+=currentLot;
							    numRevertInHand = 0;
								countRevert--;
							  }
						      else {
							    numRevertInHand-=currentLot;
						      }
						      numInHand-=currentLot;
							  handleTrade++;
				      }
					  else if (act.inOrOut == TurtleAction.OUT_ACTION && 
					      act.longOrShort == TurtleAction.SHORT_ACTION &&
					      act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_END) {
						  /*收盤出場*/	
						  if (isNowRevert == true) {
							numRevertInHand-=currentLot;
							numRevertInHand = 0;
							countRevert--;
						  }
						  else {
						    numRevertInHand+=currentLot;
						  }
						  numInHand+=currentLot;
						  handleTrade++;
					  }					 
					  
					}
				}
				prevClosePrice = today.close;
				prevADX = allStockPrices.get(iterString).adx;
				iterTime.add(Calendar.DATE, 1);			
			}

			dayProfitMap.put(iterString, new Double(currentProfit));
			histProfit.add(currentProfit);
			if (histProfit.size()>22) {
			  double delta = currentProfit - histProfit.get(histProfit.size()-2);
			  double increaseProfit20 = currentProfit - histProfit.get(histProfit.size()-21);
			  double increaseProfit10 = currentProfit - histProfit.get(histProfit.size()-11);
			  double increaseProfit5 = currentProfit - histProfit.get(histProfit.size()-6);
			  if (increaseProfit20 > 1500 && (countRevert==0) && numRevertInHand==0) {
				  if (delta<0 && increaseProfit5<increaseProfit10 && increaseProfit10<increaseProfit20) {
				    countRevert = 3;
				  }
			  }
			}
			
			try {
				writer.write(iterString+","+prevClosePrice+","+numRevertInHand+","+numInHand+","+(int)revertProfit+","+(int)currentProfit+","+prevADX+"\n");
			}catch (IOException e) {
				System.out.println(e);
			}			
		}
		try {
			writer.close();
		}catch (IOException e) {
			System.out.println(e);
		}
		
		ProfitAnalyzer analyzer = new ProfitAnalyzer(dayProfitMap);
		try {
			analyzer.analyzeBaseStatistic();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}
